package com.nononsenseapps.feeder.util

import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.provider.Browser.EXTRA_CREATE_NEW_TAB
import android.widget.Toast
import org.jsoup.Jsoup
import org.jsoup.nodes.Attributes
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import org.jsoup.nodes.TextNode
import org.jsoup.parser.Tag
import timber.log.Timber
import java.util.regex.Pattern

private val patternImgSrc: Pattern = Pattern.compile("img.*?src=[\"'](.*?)[\"']")
//private val patternImgSrc: Pattern = Pattern.compile("<img\\b[^<>]*?\\bsrc[\\s\\t\\r\\n]*=[\\s\\t\\r\\n]*[\"\"']?[\\s\\t\\r\\n]*(?<imgUrl>[^\\t\\r\\n\"\"'<>]*)[^<>]*?/?[\\s\\t\\r\\n]*>")
private val patternUrlSrc: Pattern = Pattern.compile("(([hH][tT]{2}[pP]([sS]?):/*)[a-zA-Z0-9\\.\\-]+\\.[([a-zA-Z0-9]{2,4})|[\\w-]](:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#\$%^&*+?:_/=<>[\\u4e00-\\u9fa5]*]*)+)|(www.[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#\$%^&*+?:_/=<>[\\u4e00-\\u9fa5]*]*)+)")

private val patternHttp: Pattern = Pattern.compile("(([hH][tT]{2}[pP]([sS]?):/*)([\\w-]+\\.)+[\\w-]+(:\\d+)*(/[\\w-./?%&=]*)?(?!<>))")

fun naiveFindImageLink(text: String?): String? {
    if (text != null) {
        val matcher = patternImgSrc.matcher(text)
        if (matcher.find()) {
            return matcher.group(1)?.toString()
        }
    }
    return null
}

fun naiveFindUrlLink(text: String?): String? {
    if (text != null) {
        val matcher = patternHttp.matcher(text)
        if (matcher.find()) {
            //Timber.d("find count:${matcher.groupCount()}\tmatch:"+matcher.group())
            return matcher.group(1)?.toString()
        }
    }
    return null
}

fun naiveFindImageLinkCount(text: String?):  Int? {
    if (text != null) {
        return patternImgSrc.toRegex().findAll(text).filter {
            it.groupValues[1].isNotEmpty()
        }.count()
    }
    return null
}

fun naiveFindImageLinkList(text: String?): List<String>? {
    if (text != null) {
        return patternImgSrc.toRegex().findAll(text).filter {
            it.groupValues[1].isNotEmpty()
        }.mapNotNull { it.groups[1]?.value }.toList()
    }
    return null
}

/**
 * Opens the specified link in a new tab in the browser, or otherwise suitable application. If no suitable application
 * could be found, a Toast is displayed and false is returned. Otherwise, true is returned.
 */
fun openLinkInBrowser(context: Context, link: String): Boolean {
    try {
        val intent = Intent(Intent.ACTION_VIEW, Uri.parse(link))
        intent.flags=Intent.FLAG_ACTIVITY_NEW_TASK
        intent.putExtra(EXTRA_CREATE_NEW_TAB, true)
        context.startActivity(intent)
    } catch (e: ActivityNotFoundException) {
        /*Toast.makeText(context, R.string.no_activity_for_link, Toast.LENGTH_SHORT).show()*/
        Toast.makeText(context, "no_activity_for_link", Toast.LENGTH_SHORT).show()
        return false
    }
    return true
}

fun truncateHTML(content: String?, len: Int): String? {
    val dirtyDocument = Jsoup.parse(content)
    val source = dirtyDocument.body()
    val clean = Document.createShell(dirtyDocument.baseUri())
    val dest = clean.body()
    truncateHTML(source, dest, len)
    return dest.outerHtml()
}

private  fun truncateHTML(source: Element, dest: Element, len: Int) {
    var len = len
    val sourceChildren = source.childNodes()
    for (sourceChild in sourceChildren) {
        if (sourceChild is Element) {
            val sourceEl = sourceChild
            val destChild = createSafeElement(sourceEl)
            val txt = dest.text().length
            len = if (txt >= len)
                break
            else {
                len - txt
            }
            dest.appendChild(destChild)
            truncateHTML(sourceEl, destChild, len)
        } else if (sourceChild is TextNode) {
            val destLeng = dest.text().length
            if (destLeng >= len) {
                break
            }
            val sourceText = sourceChild
            val txtLeng = sourceText.wholeText.length
            if (destLeng + txtLeng > len) {
                val tmp = len - destLeng
                val txt = sourceText.wholeText.substring(0, tmp)
                val destText = TextNode(txt)
                dest.appendChild(destText)
                break
            } else {
                val destText = TextNode(sourceText.wholeText)
                dest.appendChild(destText)
            }
        }
    }
}

private  fun createSafeElement(sourceEl: Element): Element {
    val sourceTag = sourceEl.tagName()
    val destAttrs = Attributes()
    val dest = Element(Tag.valueOf(sourceTag), sourceEl.baseUri(), destAttrs)
    val sourceAttrs = sourceEl.attributes()
    for (sourceAttr in sourceAttrs) {
        destAttrs.put(sourceAttr)
    }
    return dest
}
